package algebra;

import java.util.LinkedList;

public class PolynomialEquation {
	LinkedList<Poly> leftSide;
	LinkedList<Poly> leftSideSimplified;
	LinkedList<Poly> rightSide;
	LinkedList<Poly> rightSideSimplified;
	LinkedList<Poly> leftSlopeIntercept;
	LinkedList<Character> variables;
	double yCoefficient = 1;
	
	public PolynomialEquation(Poly p){
		leftSide = new LinkedList<Poly>();
		leftSideSimplified = new LinkedList<Poly>();
		rightSide = new LinkedList<Poly>();
		rightSideSimplified = new LinkedList<Poly>();
		variables = new LinkedList<Character>();
		//System.out.println("In constructor: " + p.coefficient);
		leftSide.add(p);
		if(p.variable != '\0'){
			variables.add(p.variable);
		}
		//leftSideSimplified.add(new Poly(p.variable, p.degree, p.coefficient));
	}
	
	public PolynomialEquation add(PolynomialEquation p, int side, char prevOp){
		if(prevOp == '*'){
			//if(side == 0){
				Poly f = leftSide.getFirst();
				Poly b = p.leftSide.getFirst();
				if(f.variable == b.variable){
					if((f.variable == '\0') && (b.variable == '\0')){
						//do nothing - only dealing with integers
					}else{
						//add the coefficients
						leftSide.getFirst().degree += b.degree;
					}
				}else if(f.variable == '\0'){
					//add the new variable and degree to the element
					leftSide.getFirst().variable = b.variable;
					leftSide.getFirst().degree = b.degree;
				}else if(b.variable == '\0'){
					//do nothing - leftSide.get(j) is an integer
				}else{
					//dealing with two different variables
				}
				leftSide.getFirst().coefficient *= b.coefficient;
				if(p.leftSide.size() > 1){
					for(int i=1; i<p.leftSide.size(); i++){
						Poly a = p.leftSide.get(i);
						//System.out.println("Before degree: "+f.degree);
						//System.out.println("Before coefficient: "+f.coefficient);
						if(f.variable == a.variable){
							if((f.variable == '\0') && (a.variable == '\0')){
								//do nothing - only dealing with integers
								if(f.prevOp == '-'){
									a.prevOp = f.prevOp;
								}else{
									a.prevOp = '+';
								}
								leftSide.add(a);
							}else{
								//add the coefficients
								if(f.prevOp == '-'){
									a.prevOp = f.prevOp;
								}else{
									a.prevOp = '+';
								}
								a.degree += f.degree;
								leftSide.add(a);
							}
						}else if(f.variable == '\0'){
							//add the new variable and degree to the element
							//leftSide.getFirst().variable = a.variable;
							//leftSide.getFirst().degree = a.degree;
							if(f.prevOp == '-'){
								a.prevOp = f.prevOp;
							}else{
								a.prevOp = '+';
							}
							leftSide.add(a);
						}else if(a.variable == '\0'){
							//do nothing - leftSide.get(j) is an integer
							if(f.prevOp == '-'){
								a.prevOp = f.prevOp;
							}else{
								a.prevOp = '+';
							}
							leftSide.add(a);
						}else{
							//dealing with two different variables
							break;
						}
						leftSide.getLast().coefficient *= f.coefficient;
						//System.out.println("After coefficient: "+leftSide.getFirst().coefficient);
						//System.out.println("After degree: "+leftSide.getFirst().degree);
					}
				}
			/*}else{
				System.out.println("Multiplying on right: "+p.leftSide.getFirst());
				Poly f = rightSide.getFirst();
				Poly b = p.leftSide.getFirst();
				if(f.variable == b.variable){
					if((f.variable == '\0') && (b.variable == '\0')){
						//do nothing - only dealing with integers
					}else{
						//add the coefficients
						rightSide.getFirst().degree += b.degree;
					}
				}else if(f.variable == '\0'){
					//add the new variable and degree to the element
					rightSide.getFirst().variable = b.variable;
					rightSide.getFirst().degree = b.degree;
				}else if(b.variable == '\0'){
					//do nothing - leftSide.get(j) is an integer
				}else{
					//dealing with two different variables
				}
				rightSide.getFirst().coefficient *= b.coefficient;
				if(p.leftSide.size() > 1){
					for(int i=1; i<p.leftSide.size(); i++){
						Poly a = p.leftSide.get(i);
						//System.out.println("   "+a);
						//System.out.println("Before degree: "+f.degree);
						//System.out.println("Before coefficient: "+f.coefficient);
						if(f.variable == a.variable){
							if((f.variable == '\0') && (a.variable == '\0')){
								//do nothing - only dealing with integers
								if(f.prevOp == '-'){
									a.prevOp = f.prevOp;
								}else{
									a.prevOp = '+';
								}
								rightSide.add(a);
							}else{
								//add the coefficients
								if(f.prevOp == '-'){
									a.prevOp = f.prevOp;
								}else{
									a.prevOp = '+';
								}
								a.degree += f.degree;
								rightSide.add(a);
							}
						}else if(f.variable == '\0'){
							//add the new variable and degree to the element
							//leftSide.getFirst().variable = a.variable;
							//leftSide.getFirst().degree = a.degree;
							if(f.prevOp == '-'){
								a.prevOp = f.prevOp;
							}else{
								a.prevOp = '+';
							}
							rightSide.add(a);
						}else if(a.variable == '\0'){
							//do nothing - leftSide.get(j) is an integer
							if(f.prevOp == '-'){
								a.prevOp = f.prevOp;
							}else{
								a.prevOp = '+';
							}
							rightSide.add(a);
						}else{
							//dealing with two different variables
							break;
						}
						rightSide.getLast().coefficient *= f.coefficient;
						//System.out.println("After coefficient: "+leftSide.getFirst().coefficient);
						//System.out.println("After degree: "+leftSide.getFirst().degree);
					}
				}
			}*/
		}else if(side == 0){
			//add to the left side
			for(int j=0; j<p.leftSide.size(); j++){
				p.leftSide.get(j).prevOp = prevOp;
				leftSide.add(p.leftSide.get(j));
			}
		}else{
			//add to the right side
			for(int j=0; j<p.leftSide.size(); j++){
				Poly temp = p.leftSide.get(j);
				rightSide.add(new Poly(temp.variable, temp.degree, temp.coefficient));
				if(prevOp != '\0'){
					rightSide.getLast().prevOp = prevOp;
				}else{
					rightSide.getLast().prevOp = temp.prevOp;
				}
			}
		}

		for(int i=0; i<p.leftSide.size(); i++){
			if(!variables.contains(p.leftSide.get(i).variable) && (p.leftSide.get(i).variable != '\0')){
				variables.add(p.leftSide.get(i).variable);
			}
		}
		if(leftSide.size() > 0 && rightSide.size() > 0){
			simplify();
		}
		//System.out.println("Equation: " + toString());
		//System.out.println("Simplist: "+printSimplist());
		return this;
	}
	
	public String toString(){
		String equ = "";
		for(int i=0; i<leftSide.size(); i++){
			Poly p = leftSide.get(i);
			if(i == 0){
				equ = equ + p;
			}else{
				equ = equ + " " + p.prevOp + " " + p;
			}
		}
		if(rightSide.size() > 0){
			equ = equ + " = ";
		}
		for(int i=0; i<rightSide.size(); i++){
			Poly p = rightSide.get(i);
			if(i == 0){
				equ = equ + p;
			}else{
				equ = equ + " " + p.prevOp + " " + p;
			}
		}
		return equ;
	}
	
	/*Returns to maximum degree in the equation*/
	public int maxDegree(){
		int max = 0;
		int d;
		for(int i=0; i<leftSide.size(); i++){
			d = leftSide.get(i).degree;
			if(d > max){
				max = d;
			}
		}
		for(int i=0; i<rightSide.size(); i++){
			d = rightSide.get(i).degree;
			if(d > max){
				max = d;
			}
		}
		return max;
	}
	
	/*Simplify the equation*/
	public void simplify(){
		leftSideSimplified.clear();
		rightSideSimplified.clear();
		Poly p = leftSide.getFirst();
		leftSideSimplified.add(new Poly(p.variable, p.degree, p.coefficient));
		for(int j=1; j<leftSide.size(); j++){
			boolean added = false;
			for(int i=0; i<leftSideSimplified.size(); i++){
				char prevOp = leftSide.get(j).prevOp;
				if((leftSideSimplified.get(i).variable == leftSide.get(j).variable)
						&& (leftSideSimplified.get(i).degree == leftSide.get(j).degree)){
					if(prevOp == '+'){
						leftSideSimplified.get(i).coefficient += leftSide.get(j).coefficient;
						added = true;
						break;
					}else if(prevOp == '-'){
						leftSideSimplified.get(i).coefficient -= leftSide.get(j).coefficient;
						added = true;
						break;
					}else if(prevOp == '/'){
						leftSideSimplified.get(i).coefficient /= leftSide.get(j).coefficient;
						added = true;
						break;
					}
				}
			}
			if(!added){
				leftSideSimplified.add(leftSide.get(j));
			}
		}
		Poly r = rightSide.getFirst();
		rightSideSimplified.add(new Poly(r.variable, r.degree, r.coefficient));
		for(int j=1; j<rightSide.size(); j++){
			boolean added = false;
			for(int i=0; i<rightSideSimplified.size(); i++){
				char prevOp = rightSide.get(j).prevOp;
				if((rightSideSimplified.get(i).variable == rightSide.get(j).variable)
						&& (rightSideSimplified.get(i).degree == rightSide.get(j).degree)){
					if(prevOp == '+'){
						rightSideSimplified.get(i).coefficient += rightSide.get(j).coefficient;
						added = true;
						break;
					}else if(prevOp == '-'){
						rightSideSimplified.get(i).coefficient -= rightSide.get(j).coefficient;
						added = true;
						break;
					}else if(prevOp == '/'){
						rightSideSimplified.get(i).coefficient /= rightSide.get(j).coefficient;
						added = true;
						break;
					}
				}
			}
			if(added == false){
				rightSideSimplified.add(rightSide.get(j));
			}
		}
		if(leftSideSimplified.getFirst().prevOp == '+'){
			leftSideSimplified.getFirst().prevOp = '\0';
		}
		if(leftSideSimplified.getFirst().prevOp == '-'){
			leftSideSimplified.getFirst().prevOp = '\0';
			leftSideSimplified.getFirst().coefficient = -1*leftSideSimplified.getFirst().coefficient;
		}
		if(rightSideSimplified.getFirst().prevOp == '+'){
			rightSideSimplified.getFirst().prevOp = '\0';
		}
		if(rightSideSimplified.getFirst().prevOp == '-'){
			rightSideSimplified.getFirst().prevOp = '\0';
			rightSideSimplified.getFirst().coefficient = -1*rightSideSimplified.getFirst().coefficient;
		}
		//System.out.println(printSimplist());
	}
	
	/*Simplifies the simplist lists*/
	public void simplifySimplist(){
		for(int i=0; i<leftSideSimplified.size()-1; i++){
			for(int j=i+1; j<leftSideSimplified.size(); j++){
				if((i>=leftSideSimplified.size()) || (j>=leftSideSimplified.size())){
					break;
				}
				if((leftSideSimplified.get(i).variable == leftSideSimplified.get(j).variable)
						&& (leftSideSimplified.get(i).degree == leftSideSimplified.get(j).degree)){
					char prevOp = leftSideSimplified.get(j).prevOp;
					double n1 = leftSideSimplified.get(i).coefficient;
					double n2 = leftSideSimplified.get(j).coefficient;
					if(prevOp == '+'){
						if(leftSideSimplified.get(i).prevOp == '-'){
							leftSideSimplified.get(i).coefficient = n1 - n2;
						}else{
							leftSideSimplified.get(i).coefficient = n1 + n2;
						}
						leftSideSimplified.remove(j);
						//added = true;
						break;
					}else if(prevOp == '-'){
						if(leftSideSimplified.get(i).prevOp == '-'){
							leftSideSimplified.get(i).coefficient = n1 + n2;
						}else{
							leftSideSimplified.get(i).coefficient = n1 - n2;
						}
						//added = true;
						leftSideSimplified.remove(j);
						break;
					}
				}
			}
		}
		for(int i=0; i<rightSideSimplified.size()-1; i++){
			for(int j=i+1; j<rightSideSimplified.size(); j++){
				if((rightSideSimplified.get(i).variable == rightSideSimplified.get(j).variable)
						&& (rightSideSimplified.get(i).degree == rightSideSimplified.get(j).degree)){
					char prevOp = rightSideSimplified.get(j).prevOp;
					if(prevOp == '+'){
						if(rightSideSimplified.get(i).prevOp == '-'){
							rightSideSimplified.get(i).coefficient -= rightSideSimplified.get(j).coefficient;
						}else{
							rightSideSimplified.get(i).coefficient += rightSideSimplified.get(j).coefficient;
						}
						rightSideSimplified.remove(j);
						//added = true;
						break;
					}else if(prevOp == '-'){
						if(rightSideSimplified.get(i).prevOp == '-'){
							rightSideSimplified.get(i).coefficient += rightSideSimplified.get(j).coefficient;
						}else{
							rightSideSimplified.get(i).coefficient -= rightSideSimplified.get(j).coefficient;
						}
						//added = true;
						rightSideSimplified.remove(j);
						break;
					}
				}
			}
		}
		if(rightSideSimplified.size() == 0){
			rightSideSimplified.add(new Poly('\0', 1, 0));
		}
		if(leftSideSimplified.size() == 0){
			leftSideSimplified.add(new Poly('0', 1, 0));
		}
		//System.out.println(printSimplist());
	}
	
	/*Returns solution for single-variable equations*/
	/*public Fraction singleVariableSolution(){
		//simplify();
		//Put integers on right side
		for(int i=0; i<leftSideSimplified.size(); i++){
			if(leftSideSimplified.get(i).variable == '\0'){
				rightSideSimplified.add(leftSideSimplified.get(i));
				switch(leftSideSimplified.get(i).prevOp){
					case '\0':
						rightSideSimplified.getLast().prevOp = '-';
						break;
					case '+':
						rightSideSimplified.getLast().prevOp = '-';
						break;
					case '-':
						rightSideSimplified.getLast().prevOp = '+';
						break;
					//case '*': rightSideSimplified.getLast().prevOp = '/';
				}	
				leftSideSimplified.remove(i);
				i--;
			}
		}
		//Put polynomials polynomials on left side
		char v = leftSideSimplified.getFirst().variable;
		for(int i=0; i<rightSideSimplified.size(); i++){
			if(rightSideSimplified.get(i).variable == v){
				leftSideSimplified.add(rightSideSimplified.get(i));
				switch(rightSideSimplified.get(i).prevOp){
					case '\0':
						leftSideSimplified.getLast().prevOp = '-';
						break;
					case '+':
						leftSideSimplified.getLast().prevOp = '-';
						break;
					case '-':
						leftSideSimplified.getLast().prevOp = '+';
						break;
				}
				rightSideSimplified.remove(i);
				i--;
			}
		}
		simplifySimplist();
		//return (double) rightSideSimplified.getFirst().coefficient / (double) leftSideSimplified.getFirst().coefficient;
		if(rightSideSimplified.getFirst().prevOp == '-'){
			return new Fraction(-1*rightSideSimplified.getFirst().coefficient, leftSideSimplified.getFirst().coefficient);
		}else{
			return new Fraction(rightSideSimplified.getFirst().coefficient, leftSideSimplified.getFirst().coefficient);
		}
	}*/

	public double singleVariableSolution(){
		//simplify();
		//Put integers on right side
		for(int i=0; i<leftSideSimplified.size(); i++){
			if(leftSideSimplified.get(i).variable == '\0'){
				rightSideSimplified.add(leftSideSimplified.get(i));
				switch(leftSideSimplified.get(i).prevOp){
					case '\0':
						rightSideSimplified.getLast().prevOp = '-';
						break;
					case '+':
						rightSideSimplified.getLast().prevOp = '-';
						break;
					case '-':
						rightSideSimplified.getLast().prevOp = '+';
						break;
					//case '*': rightSideSimplified.getLast().prevOp = '/';
				}	
				leftSideSimplified.remove(i);
				i--;
			}
		}
		
		//System.out.println(printSimplist());
		
		//Put polynomials polynomials on left side
		//char v = leftSideSimplified.getFirst().variable;
		for(int i=0; i<rightSideSimplified.size(); i++){
			if(rightSideSimplified.get(i).variable != '\0'){
				leftSideSimplified.add(rightSideSimplified.get(i));
				switch(rightSideSimplified.get(i).prevOp){
					case '\0':
						leftSideSimplified.getLast().prevOp = '-';
						break;
					case '+':
						leftSideSimplified.getLast().prevOp = '-';
						break;
					case '-':
						leftSideSimplified.getLast().prevOp = '+';
						break;
				}
				rightSideSimplified.remove(i);
				i--;
			}
		}
		simplifySimplist();
		//return (double) rightSideSimplified.getFirst().coefficient / (double) leftSideSimplified.getFirst().coefficient;
		if(rightSideSimplified.getFirst().prevOp == '-'){
			return -1*(rightSideSimplified.getFirst().coefficient/leftSideSimplified.getFirst().coefficient);
		}else{
			return rightSideSimplified.getFirst().coefficient/leftSideSimplified.getFirst().coefficient;
		}
	}
	
	public double[] quadratic(){
		System.out.println("In quadratic: "+printSimplist());
		double[] roots = new double[2];
		//Put all elements on the left side of the equation
		while(rightSideSimplified.size() > 0){
			leftSideSimplified.add(rightSideSimplified.getFirst());
			switch(rightSideSimplified.getFirst().prevOp){
				case '\0':
					leftSideSimplified.getLast().prevOp = '-';
					break;
				case '+':
					leftSideSimplified.getLast().prevOp = '-';
					break;
				case '-':
					leftSideSimplified.getLast().prevOp = '+';
					break;
			}
			rightSideSimplified.removeFirst();
		}
		
		//Add 0 to the right side
		rightSideSimplified.add(new Poly('\0', 1, 0));
		
		//System.out.println(printSimplist());
		
		//Simplify again
		simplifySimplist();
		
		//System.out.println(printSimplist());
		
		//Find a, b & c
		double a = 0;
		boolean aFound = false;
		boolean bFound = false;
		boolean cFound = false;
		double b = 0;
		double c = 0;
		for(int i=0; i < leftSideSimplified.size(); i++){
			if(leftSideSimplified.get(i).degree == 2){
				if(leftSideSimplified.get(i).prevOp == '-'){
					a = -1*leftSideSimplified.get(i).coefficient;
				}else{
					a = leftSideSimplified.get(i).coefficient;
				}
				aFound = true;
			}
			if(leftSideSimplified.get(i).degree == 1){
				if(leftSideSimplified.get(i).variable == '\0'){
					if(leftSideSimplified.get(i).prevOp == '-'){
						c = -1*leftSideSimplified.get(i).coefficient;
					}else{
						c = leftSideSimplified.get(i).coefficient;
					}
					cFound = true;
				}else{
					if(leftSideSimplified.get(i).prevOp == '-'){
						b = -1*leftSideSimplified.get(i).coefficient;
					}else{
						b = leftSideSimplified.get(i).coefficient;
					}
					bFound = true;
				}
			}
		}
		if(!aFound){
			a = 0;
		}
		if(!bFound){
			b = 0;
		}
		if(!cFound){
			c = 0;
		}
		
		//System.out.println("a = "+a+", b = "+b+", c ="+c);
		
		//Find roots
		roots[0] = (-1*b + Math.sqrt(b*b - 4*a*c)) / (2*a);
		roots[1] = (-1*b - Math.sqrt(b*b - 4*a*c)) / (2*a);
		
		if(roots[0] == -0){
			roots[0] = 0;
		}
		if(roots[1] == -0){
			roots[1] = 0;
		}
		
		return roots;
	}
	
	public double slope(){
		//Rewrite the equation to have the form y=mx + b
		slopeInterceptForm();
		
		//x coefficient is slope
		for(int i=0; i<rightSideSimplified.size(); i++){
			if(rightSideSimplified.get(i).variable == 'x'){
				if(rightSideSimplified.get(i).prevOp == '-'){
					return -1*rightSideSimplified.get(i).coefficient;
				}else{
					return rightSideSimplified.get(i).coefficient;
				}
			}
		}
		return 0;
	}
	
	public String printSlopeIntercept(){
		slopeInterceptForm();
		return printSimplist();
	}
	
	public double yIntercept(){
		//Rewrite the equation to have the form y=mx + b
		slopeInterceptForm();
		//System.out.println("Slope-Intercept Form: "+printSimplist());
		for(int i=0; i<rightSideSimplified.size(); i++){
			if(rightSideSimplified.get(i).variable == '\0'){
				if(rightSideSimplified.get(i).prevOp == '-'){
					return -1*rightSideSimplified.get(i).coefficient;
				}else{
					return rightSideSimplified.get(i).coefficient;
				}
			}
		}
		return 0;
		
	}
	
	public void slopeInterceptForm(){
		//simplify();
		//System.out.println("Simplify: ")
		//If y poly is on right, move it to left
		//System.out.println("rightSideSimplified size: "+rightSideSimplified.size());
		for(int i=0; i<rightSideSimplified.size(); i++){
			if(rightSideSimplified.get(i).variable == 'y'){
				leftSideSimplified.add(rightSideSimplified.get(i));
				//System.out.println("Moving right to left: "+rightSideSimplified.get(i));
				switch(rightSideSimplified.get(i).prevOp){
					case '\0':
						leftSideSimplified.getLast().prevOp = '-';
						break;
					case '+':
						leftSideSimplified.getLast().prevOp = '-';
						break;
					case '-':
						leftSideSimplified.getLast().prevOp = '+';
						break;
				}
				rightSideSimplified.remove(i);
			}
		}
		//Move other polys to the right
		//System.out.println("leftSideSimplified size: "+leftSideSimplified.size());
		for(int j=0; j<leftSideSimplified.size(); j++){
			//System.out.println("On left side: "+leftSideSimplified.get(j));
			if((leftSideSimplified.get(j).variable == 'x') || (leftSideSimplified.get(j).variable == '\0')){
				rightSideSimplified.add(leftSideSimplified.get(j));
				//System.out.println("Moving left to right: "+leftSideSimplified.get(j));
				switch(leftSideSimplified.get(j).prevOp){
					case '\0':
						rightSideSimplified.getLast().prevOp = '-';
						break;
					case '+':
						rightSideSimplified.getLast().prevOp = '-';
						break;
					case '-':
						rightSideSimplified.getLast().prevOp = '+';
						break;
					//case '*': rightSideSimplified.getLast().prevOp = '/';
				}	
				leftSideSimplified.remove(j);
				j--;
			}
		}
		if(rightSideSimplified.getFirst().prevOp == '-'){
			System.out.println("First coefficient is negative");
			for(int i=0; i<leftSideSimplified.size(); i++){
				if(leftSideSimplified.get(i).prevOp == '+'){
					leftSideSimplified.get(i).prevOp = '-';
				}else if(leftSideSimplified.get(i).prevOp == '-'){
					leftSideSimplified.get(i).prevOp = '+';
				}
			}
			for(int i=0; i<rightSideSimplified.size(); i++){
				if(rightSideSimplified.get(i).prevOp == '+'){
					rightSideSimplified.get(i).prevOp = '-';
				}else if(rightSideSimplified.get(i).prevOp == '-'){
					rightSideSimplified.get(i).prevOp = '+';
				}
			}
		}
		
		
		//Check if y has a coefficient. If it does, divide other coefficients by the y-coefficient
		yCoefficient = leftSideSimplified.getFirst().coefficient;
		if(yCoefficient != 1){
			for(int i=0; i<rightSideSimplified.size(); i++){
				rightSideSimplified.get(i).coefficient /= yCoefficient;
			}
			leftSideSimplified.getFirst().coefficient = 1;
		}
		
		//Check that Ax comes before By
		if(leftSideSimplified.getFirst().variable == 'y'){
			Poly yPoly = leftSideSimplified.removeFirst();
			if(yPoly.coefficient < 0){
				yPoly.prevOp = '-';
				yPoly.coefficient *= -1;
			}else{
				yPoly.prevOp = '+';
			}
			leftSideSimplified.addLast(yPoly);
		}
		
		correctCoefficients();
		simplifySimplist();
		
		//System.out.println("Slope-Intercept Form: "+printSimplist());
	}
	
	public void generalForm(){
		//simplify();
		//If constant is on the left side, move it to the right
		for(int i=0; i<leftSideSimplified.size(); i++){
			if(leftSideSimplified.get(i).variable == '\0'){
				rightSideSimplified.add(leftSideSimplified.get(i));
				//System.out.println("Moving left to right: "+leftSideSimplified.get(j));
				switch(leftSideSimplified.get(i).prevOp){
					case '\0':
						rightSideSimplified.getLast().prevOp = '-';
						break;
					case '+':
						rightSideSimplified.getLast().prevOp = '-';
						break;
					case '-':
						rightSideSimplified.getLast().prevOp = '+';
						break;
				}	
				leftSideSimplified.remove(i);
				i--;
			}
		}
		
		//Move Ax and By to the left side
		for(int i=0; i<rightSideSimplified.size(); i++){
			if(rightSideSimplified.get(i).variable != '\0'){
				leftSideSimplified.add(rightSideSimplified.get(i));
				//System.out.println("Moving right to left: "+rightSideSimplified.get(i));
				switch(rightSideSimplified.get(i).prevOp){
					case '\0':
						leftSideSimplified.getLast().prevOp = '-';
						break;
					case '+':
						leftSideSimplified.getLast().prevOp = '-';
						break;
					case '-':
						leftSideSimplified.getLast().prevOp = '+';
						break;
				}
				rightSideSimplified.remove(i);
				i--;
			}
		}
		
		for(int i=0; i<leftSideSimplified.size(); i++){
			leftSideSimplified.get(i).coefficient *= yCoefficient;
		}
		for(int i=0; i<rightSideSimplified.size(); i++){
			rightSideSimplified.get(i).coefficient *= yCoefficient;
		}
		
		//Check that Ax comes before By
		if(leftSideSimplified.getFirst().variable == 'y'){
			Poly yPoly = leftSideSimplified.removeFirst();
			if(yPoly.coefficient < 0){
				yPoly.prevOp = '-';
				yPoly.coefficient *= -1;
			}else{
				yPoly.prevOp = '+';
			}
			leftSideSimplified.addLast(yPoly);
		}
		
		System.out.println(printSimplist());
		
		
		
		correctCoefficients();
		simplifySimplist();
	}
	
	public String printGeneralForm(){
		generalForm();
		return printSimplist();
	}
	
	public void correctCoefficients(){
		if(leftSideSimplified.size() == 0 || rightSideSimplified.size() == 0){
			return;
		}
		if(leftSideSimplified.getFirst().prevOp == '+'){
			leftSideSimplified.getFirst().prevOp = '\0';
		}
		if(leftSideSimplified.getFirst().prevOp == '-'){
			leftSideSimplified.getFirst().prevOp = '\0';
			leftSideSimplified.getFirst().coefficient = -1*leftSideSimplified.getFirst().coefficient;
		}
		if(rightSideSimplified.getFirst().prevOp == '+'){
			rightSideSimplified.getFirst().prevOp = '\0';
		}
		if(rightSideSimplified.getFirst().prevOp == '-'){
			rightSideSimplified.getFirst().prevOp = '\0';
			rightSideSimplified.getFirst().coefficient = -1*rightSideSimplified.getFirst().coefficient;
		}
		for(int i=1; i<leftSideSimplified.size(); i++){
			if(leftSideSimplified.get(i).coefficient < 0 && leftSideSimplified.get(i).prevOp == '-'){
				leftSideSimplified.get(i).prevOp = '+';
				leftSideSimplified.get(i).coefficient *= -1;
			}
		}
		for(int i=1; i<rightSideSimplified.size(); i++){
			if(rightSideSimplified.get(i).coefficient < 0 && rightSideSimplified.get(i).prevOp == '-'){
				rightSideSimplified.get(i).prevOp = '+';
				rightSideSimplified.get(i).coefficient *= -1;
			}
		}
	}
	
	public String printSimplist(){
		String simpEqu = "";
		if(leftSideSimplified.size() == 1){
			simpEqu = simpEqu + leftSideSimplified.getFirst();
		}else{
			for(int i=0; i<leftSideSimplified.size(); i++){
				Poly p = leftSideSimplified.get(i);
				if(p.coefficient != 0){
					if(i == 0){
						simpEqu = simpEqu + p;
					}else{
						simpEqu = simpEqu + " " + p.prevOp + " " + p;
					}
				}
			}
		}
		if(rightSideSimplified.size() > 0){
			simpEqu = simpEqu + " = ";
		}
		if(rightSideSimplified.size() == 1){
			simpEqu = simpEqu + rightSideSimplified.getFirst();
		}else{
			for(int i=0; i<rightSideSimplified.size(); i++){
				Poly p = rightSideSimplified.get(i);
				if(p.coefficient != 0){
					if(i == 0){
						simpEqu = simpEqu + p;
					}else{
						simpEqu = simpEqu + " " + p.prevOp + " " + p;
					}
				}
			}
		}
		return /*"Simplified Equation: */"" + simpEqu;
	}
	
}